package basis.ioc;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Client {
    public static void main(String[] args) {
        test3();
    }

    private static void test3() {
        IVehicle vehicle = VehicleFactory.createIVehicle("basis.basis.ioc.BMW");
        vehicle.moveForward(200);
    }

    private static void test2() {
        BMW bmw = createObj("basis.basis.ioc.BMW");
        System.out.println(bmw.getEnergy());

        try {
            Object o = createObj(
                    Class.forName("basis.basis.ioc.BMW").getConstructor(Integer.TYPE),
                    100);
            if (o instanceof BMW) {
                System.out.println(((BMW) o).getEnergy());
            }
            invokeTest(bmw, "moveForward", Integer.TYPE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * basis.ioc，创建对象的控制权反转
     * 通过反射，将对象创建的控制权转移给JVM
     */
    private static void test1() throws Exception {
        Class<?> clazz;
        IVehicle bmw = (BMW) (clazz = Class.forName("basis.basis.ioc.BMW"))
                .getConstructor()
                .newInstance();
        bmw.moveForward(500);
        System.out.println(bmw.getEnergy());

        Method[] methods = clazz.getMethods();
        Constructor<?>[] constructors = clazz.getConstructors();
        Field[] fields = clazz.getFields();
        Class<?> superclass = clazz.getSuperclass();
        Class<?>[] interfaces = clazz.getInterfaces();
        System.out.println("\n==== methods ====");
        for (Method m : methods) {
            System.out.println(m);
        }
        System.out.println("\n==== constructor ====");
        for (Constructor c : constructors) {
            System.out.println(c);
        }
        System.out.println("\n==== fields ====");
        for (Field f : fields) {
            System.out.println(f);
            Class<?> type = f.getType();
            System.out.println(type);

        }
        System.out.println("\n==== super class ====");
        System.out.println(superclass);
        System.out.println("\n==== interfaces ====");
        for (Class i : interfaces) {
            System.out.println(i);
        }
    }

    /**
     * 根据类名，无参创建类对象
     * 类名必须是完整的类名
     */
    public static BMW createObj(String className) {
        try {
            Object o = Class.forName(className)
                    .getConstructor()
                    .newInstance();
            if (o instanceof BMW) {
                return (BMW) o;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 调用有参构造器创建对象
     */
    public static Object createObj(Constructor<?> constructor, Object ...args) {
        try {
            Object o = constructor.newInstance(args);
            System.out.println("Object: " + o.toString());
            return o;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void invokeTest(BMW bmw, String methodName, Class<?> ...paraType) {
        Method method = null;
        try {
            method = BMW.class.getMethod(methodName, paraType);
            Object o = method.invoke(bmw, 300);
            System.out.println("result = " + o);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
